From ea91ab1d9917bc4990728bda24c54f25f1e1b0ba Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 27 Oct 2017 17:13:40 -0400 Subject: [PATCH] gsk: Make text nodes more compact The copy of the PangoGlyphString we do here was showing up in some profiles. To avoid it, allocate the PangoGlyphInfo array as part of the node itself. Update all callers to deal with the slight api change required for this. --- gsk/gskrendernode.h | 6 +++-- gsk/gskrendernodeimpl.c | 34 +++++++++++++++++-------- gsk/gskvulkancolortextpipeline.c | 9 ++++--- gsk/gskvulkancolortextpipelineprivate.h | 3 ++- gsk/gskvulkanrenderpass.c | 13 ++++++---- gsk/gskvulkantextpipeline.c | 9 ++++--- gsk/gskvulkantextpipelineprivate.h | 3 ++- gtk/inspector/recorder.c | 9 ++++--- 8 files changed, 54 insertions(+), 32 deletions(-) diff --git a/gsk/gskrendernode.h b/gsk/gskrendernode.h index 4e14038634..c72cbd84bc 100644 --- a/gsk/gskrendernode.h +++ b/gsk/gskrendernode.h @@ -294,8 +294,10 @@ GskRenderNode * gsk_text_node_new (PangoFont double y); GDK_AVAILABLE_IN_3_94 const PangoFont * gsk_text_node_peek_font (GskRenderNode *node); -GDK_AVAILABLE_IN_3_94 -const PangoGlyphString *gsk_text_node_peek_glyphs (GskRenderNode *node); +GDK_AVAILABLE_IN_3_94 +guint gsk_text_node_get_num_glyphs (GskRenderNode *node); +GDK_AVAILABLE_IN_3_94 +const PangoGlyphInfo *gsk_text_node_peek_glyphs (GskRenderNode *node); GDK_AVAILABLE_IN_3_94 const GdkRGBA * gsk_text_node_peek_color (GskRenderNode *node); GDK_AVAILABLE_IN_3_94 diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c index 6e502d0d4e..621489b6dd 100644 --- a/gsk/gskrendernodeimpl.c +++ b/gsk/gskrendernodeimpl.c @@ -3854,11 +3854,13 @@ struct _GskTextNode GskRenderNode render_node; PangoFont *font; - PangoGlyphString *glyphs; GdkRGBA color; double x; double y; + + guint num_glyphs; + PangoGlyphInfo glyphs[]; }; static void @@ -3867,7 +3869,6 @@ gsk_text_node_finalize (GskRenderNode *node) GskTextNode *self = (GskTextNode *) node; g_object_unref (self->font); - pango_glyph_string_free (self->glyphs); } #ifndef STACK_BUFFER_SIZE @@ -3897,15 +3898,15 @@ gsk_text_node_draw (GskRenderNode *node, cairo_set_scaled_font (cr, scaled_font); gdk_cairo_set_source_rgba (cr, &self->color); - if (self->glyphs->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs)) - cairo_glyphs = g_new (cairo_glyph_t, self->glyphs->num_glyphs); + if (self->num_glyphs > (int) G_N_ELEMENTS (stack_glyphs)) + cairo_glyphs = g_new (cairo_glyph_t, self->num_glyphs); else cairo_glyphs = stack_glyphs; count = 0; - for (i = 0; i < self->glyphs->num_glyphs; i++) + for (i = 0; i < self->num_glyphs; i++) { - PangoGlyphInfo *gi = &self->glyphs->glyphs[i]; + PangoGlyphInfo *gi = &self->glyphs[i]; if (gi->glyph != PANGO_GLYPH_EMPTY) { @@ -3947,9 +3948,9 @@ gsk_text_node_serialize (GskRenderNode *node) s = pango_font_description_to_string (desc); g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(uiiii)")); - for (i = 0; i < self->glyphs->num_glyphs; i++) + for (i = 0; i < self->num_glyphs; i++) { - PangoGlyphInfo *glyph = &self->glyphs->glyphs[i]; + PangoGlyphInfo *glyph = &self->glyphs[i]; g_variant_builder_add (&builder, "(uiiii)", glyph->glyph, glyph->geometry.width, @@ -4071,13 +4072,14 @@ gsk_text_node_new (PangoFont *font, if (ink_rect.width == 0 || ink_rect.height == 0) return NULL; - self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, 0); + self = (GskTextNode *) gsk_render_node_new (&GSK_TEXT_NODE_CLASS, sizeof (PangoGlyphInfo) * glyphs->num_glyphs); self->font = g_object_ref (font); - self->glyphs = pango_glyph_string_copy (glyphs); self->color = *color; self->x = x; self->y = y; + self->num_glyphs = glyphs->num_glyphs; + memcpy (self->glyphs, glyphs->glyphs, sizeof (PangoGlyphInfo) * glyphs->num_glyphs); graphene_rect_init (&self->render_node.bounds, x, @@ -4108,7 +4110,17 @@ gsk_text_node_peek_font (GskRenderNode *node) return self->font; } -const PangoGlyphString * +guint +gsk_text_node_get_num_glyphs (GskRenderNode *node) +{ + GskTextNode *self = (GskTextNode *) node; + + g_return_val_if_fail (GSK_IS_RENDER_NODE_TYPE (node, GSK_TEXT_NODE), 0); + + return self->num_glyphs; +} + +const PangoGlyphInfo * gsk_text_node_peek_glyphs (GskRenderNode *node) { GskTextNode *self = (GskTextNode *) node; diff --git a/gsk/gskvulkancolortextpipeline.c b/gsk/gskvulkancolortextpipeline.c index a35e7342c7..654b30ccef 100644 --- a/gsk/gskvulkancolortextpipeline.c +++ b/gsk/gskvulkancolortextpipeline.c @@ -98,7 +98,8 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline * GskVulkanRenderer *renderer, const graphene_rect_t *rect, PangoFont *font, - PangoGlyphString *glyphs, + guint total_glyphs, + const PangoGlyphInfo *glyphs, float x, float y, guint start_glyph, @@ -110,11 +111,11 @@ gsk_vulkan_color_text_pipeline_collect_vertex_data (GskVulkanColorTextPipeline * int x_position = 0; for (i = 0; i < start_glyph; i++) - x_position += glyphs->glyphs[i].geometry.width; + x_position += glyphs[i].geometry.width; - for (; i < glyphs->num_glyphs && count < num_glyphs; i++) + for (; i < total_glyphs && count < num_glyphs; i++) { - PangoGlyphInfo *gi = &glyphs->glyphs[i]; + const PangoGlyphInfo *gi = &glyphs[i]; if (gi->glyph != PANGO_GLYPH_EMPTY) { diff --git a/gsk/gskvulkancolortextpipelineprivate.h b/gsk/gskvulkancolortextpipelineprivate.h index bf116c31f9..9a933ef27a 100644 --- a/gsk/gskvulkancolortextpipelineprivate.h +++ b/gsk/gskvulkancolortextpipelineprivate.h @@ -26,7 +26,8 @@ void gsk_vulkan_color_text_pipeline_collect_vertex_data (Gs GskVulkanRenderer *renderer, const graphene_rect_t *rect, PangoFont *font, - PangoGlyphString *glyphs, + guint total_glyphs, + const PangoGlyphInfo *glyphs, float x, float y, guint start_glyph, diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 029c99ecf0..09ba75634c 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -371,7 +371,8 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, case GSK_TEXT_NODE: { const PangoFont *font = gsk_text_node_peek_font (node); - const PangoGlyphString *glyphs = gsk_text_node_peek_glyphs (node); + const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node); + guint num_glyphs = gsk_text_node_get_num_glyphs (node); int i; guint count; guint texture_index; @@ -406,9 +407,9 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self, op.text.start_glyph = 0; op.text.texture_index = G_MAXUINT; - for (i = 0, count = 0; i < glyphs->num_glyphs; i++) + for (i = 0, count = 0; i < num_glyphs; i++) { - PangoGlyphInfo *gi = &glyphs->glyphs[i]; + const PangoGlyphInfo *gi = &glyphs[i]; if (gi->glyph != PANGO_GLYPH_EMPTY && !(gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)) { @@ -1225,7 +1226,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), &op->text.node->bounds, (PangoFont *)gsk_text_node_peek_font (op->text.node), - (PangoGlyphString *)gsk_text_node_peek_glyphs (op->text.node), + gsk_text_node_get_num_glyphs (op->text.node), + gsk_text_node_peek_glyphs (op->text.node), gsk_text_node_peek_color (op->text.node), gsk_text_node_get_x (op->text.node), gsk_text_node_get_y (op->text.node), @@ -1243,7 +1245,8 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer (render)), &op->text.node->bounds, (PangoFont *)gsk_text_node_peek_font (op->text.node), - (PangoGlyphString *)gsk_text_node_peek_glyphs (op->text.node), + gsk_text_node_get_num_glyphs (op->text.node), + gsk_text_node_peek_glyphs (op->text.node), gsk_text_node_get_x (op->text.node), gsk_text_node_get_y (op->text.node), op->text.start_glyph, diff --git a/gsk/gskvulkantextpipeline.c b/gsk/gskvulkantextpipeline.c index 2539ad3b87..5cdeb15a1f 100644 --- a/gsk/gskvulkantextpipeline.c +++ b/gsk/gskvulkantextpipeline.c @@ -105,7 +105,8 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline, GskVulkanRenderer *renderer, const graphene_rect_t *rect, PangoFont *font, - PangoGlyphString *glyphs, + guint total_glyphs, + const PangoGlyphInfo *glyphs, const GdkRGBA *color, float x, float y, @@ -118,11 +119,11 @@ gsk_vulkan_text_pipeline_collect_vertex_data (GskVulkanTextPipeline *pipeline, int x_position = 0; for (i = 0; i < start_glyph; i++) - x_position += glyphs->glyphs[i].geometry.width; + x_position += glyphs[i].geometry.width; - for (; i < glyphs->num_glyphs && count < num_glyphs; i++) + for (; i < total_glyphs && count < num_glyphs; i++) { - PangoGlyphInfo *gi = &glyphs->glyphs[i]; + const PangoGlyphInfo *gi = &glyphs[i]; if (gi->glyph != PANGO_GLYPH_EMPTY) { diff --git a/gsk/gskvulkantextpipelineprivate.h b/gsk/gskvulkantextpipelineprivate.h index 7701fbb4bb..064045e469 100644 --- a/gsk/gskvulkantextpipelineprivate.h +++ b/gsk/gskvulkantextpipelineprivate.h @@ -26,7 +26,8 @@ void gsk_vulkan_text_pipeline_collect_vertex_data (GskVulka GskVulkanRenderer *renderer, const graphene_rect_t *rect, PangoFont *font, - PangoGlyphString *glyphs, + guint total_glyphs, + const PangoGlyphInfo *glyphs, const GdkRGBA *color, float x, float y, diff --git a/gtk/inspector/recorder.c b/gtk/inspector/recorder.c index 64236933e1..be2c3a3ab1 100644 --- a/gtk/inspector/recorder.c +++ b/gtk/inspector/recorder.c @@ -379,8 +379,9 @@ populate_render_node_properties (GtkListStore *store, case GSK_TEXT_NODE: { const PangoFont *font = gsk_text_node_peek_font (node); - const PangoGlyphString *glyphs = gsk_text_node_peek_glyphs (node); + const PangoGlyphInfo *glyphs = gsk_text_node_peek_glyphs (node); const GdkRGBA *color = gsk_text_node_peek_color (node); + guint num_glyphs = gsk_text_node_get_num_glyphs (node); float x = gsk_text_node_get_x (node); float y = gsk_text_node_get_y (node); PangoFontDescription *desc; @@ -393,9 +394,9 @@ populate_render_node_properties (GtkListStore *store, g_free (tmp); pango_font_description_free (desc); - s = g_string_sized_new (6 * glyphs->num_glyphs); - for (i = 0; i < glyphs->num_glyphs; i++) - g_string_append_printf (s, "%x ", glyphs->glyphs[i].glyph); + s = g_string_sized_new (6 * num_glyphs); + for (i = 0; i < num_glyphs; i++) + g_string_append_printf (s, "%x ", glyphs[i].glyph); add_text_row (store, "Glyphs", s->str); g_string_free (s, TRUE); -- 2.30.2